<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- 
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License. 
-->
<html>
<head>
    <link type="text/css" rel="stylesheet" href="https://struts.apache.org/css/default.css">
    <style type="text/css">
        .dp-highlighter {
            width:95% !important;
        }
    </style>
    <style type="text/css">
        .footer {
            background-image:      url('https://cwiki.apache.org/confluence/images/border/border_bottom.gif');
            background-repeat:     repeat-x;
            background-position:   left top;
            padding-top:           4px;
            color:                 #666;
        }
    </style>
    <link href='https://struts.apache.org/highlighter/style/shCoreStruts.css' rel='stylesheet' type='text/css' />
    <link href='https://struts.apache.org/highlighter/style/shThemeStruts.css' rel='stylesheet' type='text/css' />
    <script src='https://struts.apache.org/highlighter/js/shCore.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushPlain.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushXml.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushJava.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushJScript.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushGroovy.js' type='text/javascript'></script>
    <script src='https://struts.apache.org/highlighter/js/shBrushBash.js' type='text/javascript'></script>
    <script type="text/javascript">
        SyntaxHighlighter.defaults['toolbar'] = false;
        SyntaxHighlighter.all();
    </script>
    <script type="text/javascript" language="javascript">
        var hide = null;
        var show = null;
        var children = null;

        function init() {
            /* Search form initialization */
            var form = document.forms['search'];
            if (form != null) {
                form.elements['domains'].value = location.hostname;
                form.elements['sitesearch'].value = location.hostname;
            }

            /* Children initialization */
            hide = document.getElementById('hide');
            show = document.getElementById('show');
            children = document.all != null ?
                    document.all['children'] :
                    document.getElementById('children');
            if (children != null) {
                children.style.display = 'none';
                show.style.display = 'inline';
                hide.style.display = 'none';
            }
        }

        function showChildren() {
            children.style.display = 'block';
            show.style.display = 'none';
            hide.style.display = 'inline';
        }

        function hideChildren() {
            children.style.display = 'none';
            show.style.display = 'inline';
            hide.style.display = 'none';
        }
    </script>
    <title>RomeResult</title>
</head>
<body onload="init()">
<table border="0" cellpadding="2" cellspacing="0" width="100%">
    <tr class="topBar">
        <td align="left" valign="middle" class="topBarDiv" align="left" nowrap>
            &nbsp;<a href="home.html">Home</a>&nbsp;&gt;&nbsp;<a href="faqs.html">FAQs</a>&nbsp;&gt;&nbsp;<a href="cookbook.html">Cookbook</a>&nbsp;&gt;&nbsp;<a href="romeresult.html">RomeResult</a>
        </td>
        <td align="right" valign="middle" nowrap>
            <form name="search" action="https://www.google.com/search" method="get">
                <input type="hidden" name="ie" value="UTF-8" />
                <input type="hidden" name="oe" value="UTF-8" />
                <input type="hidden" name="domains" value="" />
                <input type="hidden" name="sitesearch" value="" />
                <input type="text" name="q" maxlength="255" value="" />
                <input type="submit" name="btnG" value="Google Search" />
            </form>
        </td>
    </tr>
</table>

<div id="PageContent">
    <div class="pageheader" style="padding: 6px 0px 0px 0px;">
        <!-- We'll enable this once we figure out how to access (and save) the logo resource -->
        <!--img src="/wiki/images/confluence_logo.gif" style="float: left; margin: 4px 4px 4px 10px;" border="0"-->
        <div style="margin: 0px 10px 0px 10px" class="smalltext">Apache Struts 2 Documentation</div>
        <div style="margin: 0px 10px 8px 10px"  class="pagetitle">RomeResult</div>

        <div class="greynavbar" align="right" style="padding: 2px 10px; margin: 0px;">
            <a href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=14266">
                <img src="https://cwiki.apache.org/confluence/images/icons/notep_16.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Edit Page"></a>
            <a href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=14266">Edit Page</a>
            &nbsp;
            <a href="https://cwiki.apache.org/confluence/pages/listpages.action?key=WW">
                <img src="https://cwiki.apache.org/confluence/images/icons/browse_space.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Browse Space"></a>
            <a href="https://cwiki.apache.org/confluence/pages/listpages.action?key=WW">Browse Space</a>
            &nbsp;
            <a href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=14266">
                <img src="https://cwiki.apache.org/confluence/images/icons/add_page_16.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Add Page"></a>
            <a href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=14266">Add Page</a>
            &nbsp;
            <a href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=14266">
                <img src="https://cwiki.apache.org/confluence/images/icons/add_blogentry_16.gif"
                     height="16" width="16" border="0" align="absmiddle" title="Add News"></a>
            <a href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=14266">Add News</a>
        </div>
    </div>

    <div class="pagecontent">
        <div class="wiki-content">
            <div id="ConfluenceContent"><div class="confluence-information-macro confluence-information-macro-information"><p class="title">Now available as a Struts 2 plugin</p><span class="aui-icon aui-icon-small aui-iconfont-info confluence-information-macro-icon"></span><div class="confluence-information-macro-body">
<p>The RomeResult is now available as a Struts 2 plugin over at <a shape="rect" class="external-link" href="http://code.google.com/p/s2-rome" rel="nofollow">http://code.google.com/p/s2-rome</a>.</p></div></div>

<p>A couple of days ago I quickly had to create a result type that would transform a Rome (<a shape="rect" class="external-link" href="https://rome.dev.java.net/" rel="nofollow">https://rome.dev.java.net/</a>) SyndFeed to several news feeds. The framework makes this very, very easy.</p>
<div class="confluence-information-macro confluence-information-macro-information"><p class="title">Used versions</p><span class="aui-icon aui-icon-small aui-iconfont-info confluence-information-macro-icon"></span><div class="confluence-information-macro-body">
<p>WebWork 2.2 beta 4<br clear="none">
Rome 0.7 beta</p></div></div>

<h2 id="RomeResult-Thecode">The code</h2>

<div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>com.acme.result.RomeResult.java</b></div><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
/**
 *
 */
package com.acme.result;

import java.io.Writer;

import org.apache.log4j.Logger;

import org.apache..ServletActionContext;
import com.opensymphony.xwork.ActionInvocation;
import com.opensymphony.xwork.Result;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.SyndFeedOutput;

/**
 * A simple Result to output a Rome SyndFeed object into a newsfeed.
 * @author Philip Luppens
 *
 */
public class RomeResult implements Result {

	private String feedName;

	private String feedType;

	private final static Logger logger = Logger.getLogger(RomeResult.class);

	/*
	 * (non-Javadoc)
	 *
	 * @see com.opensymphony.xwork.Result#execute(com.opensymphony.xwork.ActionInvocation)
	 */
	public void execute(ActionInvocation ai) throws Exception {
		if (feedName == null) {
			// ack, we need this to find the feed on the stack
			logger
					.error("Required parameter 'feedName' not found. "
							+ "Make sure you have the param tag set and "
							+ "the static-parameters interceptor enabled in your interceptor stack.");
			// no point in continuing ..
			return;
		}

		// don't forget to set the content to the correct mimetype
		ServletActionContext.getResponse().setContentType("text/xml");
		// get the feed from the stack that can be found by the feedName
		SyndFeed feed = (SyndFeed) ai.getStack().findValue(feedName);

		if (logger.isDebugEnabled()) {
			logger.debug("Found object on stack with name '" + feedName + "': "
					+ feed);
		}
		if (feed != null) {

			if (feedType != null) {
				// Accepted types are: rss_0.90 - rss_2.0 and atom_0.3
				// There is a bug though in the rss 2.0 generator when it checks
				// for the type attribute in the description element. It's has a
				// big 'FIXME' next to it (v. 0.7beta).
				feed.setFeedType(feedType);
			}
			SyndFeedOutput output = new SyndFeedOutput();
			//we'll need the writer since Rome doesn't support writing to an outputStream yet
			Writer out = null;
			try {
				out = ServletActionContext.getResponse().getWriter();
				output.output(feed, out);
			} catch (Exception e) {
				// Woops, couldn't write the feed ?
				logger.error("Could not write the feed", e);
			} finally {
				//close the output writer (will flush automatically)
				if (out != null) {
					out.close();
				}
			}

		} else {
			// woops .. no object found on the stack with that name ?
			logger.error("Did not find object on stack with name '" + feedName
					+ "'");
		}
	}

	public void setFeedName(String feedName) {
		this.feedName = feedName;
	}

	public void setFeedType(String feedType) {
		this.feedType = feedType;
	}

}
</pre>
</div></div>

<h2 id="RomeResult-CodeExplanation">Code Explanation</h2>

<p>Easy enough. We try to find the SyndFeed object on the WW stack. If we can find it, we will set the feed type (rss v0.9 +, atom 0.3) if it has been specified in the result parameters (see below). Then we use a SyndFeedOutput to write our newsfeed to our PrintWriter from our response.</p>

<h2 id="RomeResult-ActionConfiguration">Action Configuration</h2>

<p>Before you can use this result, you will need to register it in your <code>struts.xml</code>:</p>
<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: xml; gutter: false; theme: Default" style="font-size:12px;">
&lt;package name="default" extends="struts-default"&gt;
	&lt;result-types&gt;
		&lt;result-type name="feed" class="com.acme.result.RomeResult"/&gt;
	&lt;/result-types&gt;
	&lt;interceptors&gt;
..
</pre>
</div></div>
<p>You can now use this result type. So, create an Action that will create and populate the Rome SyndFeed, and make sure you provide a getter for your populated SyndFeed. The actual creation of your feed is beyond this recipe, but you can find plenty of examples in the Rome Wiki (<a shape="rect" class="external-link" href="http://wiki.java.net/bin/view/Javawsxml/Rome05Tutorials" rel="nofollow">http://wiki.java.net/bin/view/Javawsxml/Rome05Tutorials</a>).</p>
<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: xml; gutter: false; theme: Default" style="font-size:12px;">
&lt;action name="feed" class="com.acme.action.CreateFeedAction"&gt;
	&lt;result name="success" type="feed"&gt;
		&lt;param name="feedName"&gt;feed&lt;/param&gt;
		&lt;param name="feedType"&gt;rss_1.0&lt;/param&gt;
	&lt;/result&gt;
&lt;/action&gt;
</pre>
</div></div>

<h2 id="RomeResult-Summary">Summary </h2>

<p>This is a simple feed result using Rome as a news feed generator. You might want to make sure you don't generate your feed on every request, but there are lots of ways to deal with such problems. You can also provi<br clear="none">
de additional setters in the Result to set your feed title, url, etc, but this should suffice for a quickstart.</p></div>
        </div>

        
    </div>
</div>
<div class="footer">
    Generated by CXF SiteExporter
</div>
</body>
</html>
